
import 'dart:convert';
import 'dart:core' as prefix0;
import 'dart:core';

import 'package:dio/dio.dart';
import 'package:flustars/flustars.dart';
import 'package:flutter/services.dart';
import 'baseentity.dart';
import 'errorhandle.dart';
import 'intercept.dart';

/**
 * lx
 * git：https://gitee.com/twopai
 * dio封装，可设置header、baseUrl、拦截器
 */
class DioUtils {

  static final DioUtils _singleton = DioUtils._internal();

  static DioUtils get instance => DioUtils();

  static  String _baseUrl='';

  factory DioUtils() {
    return _singleton;
  }

  static Dio? _dio;

  DioUtils._internal(){
    var options = BaseOptions(
      connectTimeout: 15000,
      receiveTimeout: 30000,
      responseType: ResponseType.plain,
      validateStatus: (status){
        // 不使用http状态码判断状态，使用AdapterInterceptor来处理（适用于标准REST风格）
        return true;
      },
      baseUrl: _baseUrl,
    );
    _dio = Dio(options);
    /// 打印Log
    _dio!.interceptors.add(LoggingInterceptor());
    /// 适配数据
    _dio!.interceptors.add(AdapterInterceptor());
  }
  //初始化dio
  initDio({String baseUrl:''}){
    _baseUrl=baseUrl;
  }

  //添加拦截器
  DioUtils addInterceptor({Interceptor? interceptor}){
    if(interceptor!=null)_dio?.interceptors?.add(interceptor);
    return this;
  }
  //切换baseUrl
  DioUtils setBaseUrl({String? baseUrl:''}){
    if((baseUrl??'').isEmpty){
      _dio?.options?.baseUrl=_baseUrl;
    }else{
      _dio?.options?.baseUrl=baseUrl??_baseUrl;
    }
    return this;
  }
  //设置 Headers
  DioUtils setHeaders({List<Map<String,dynamic>>? headers}){
    if((headers??[]).isNotEmpty){
      headers?.forEach((element) {
        _dio?.options?.headers?.addAll(element);
      });
    }
    return this;
  }

  Options _checkOptions(method, Options? options) {
    if (options == null) options = new Options();
    if(options.headers==null){
      options.headers={};
    }
    // options.headers.addAll({'Authorization':'Bearer ${Provider.of<UserProvider>(navigatorKey.currentContext,listen: false)?.access_token}'});
    // options.headers.addAll({'Authorization':'Bearer ${SpUtils.getString(Constants.access_token)}'});
    options.method = method;
    return options;
  }

  // 数据返回格式统一，统一处理异常
  Future<BaseEntity<T>> _request<T>(String method, String url, {
    bool isFormData:false,
    dynamic data,Map<String, dynamic>? queryParameters, CancelToken? cancelToken, Options? options,Function? generateOBJ}) async {
    var response = await _dio?.request(
        url,
        data: isFormData?FormData.fromMap(data):(data),
        queryParameters:queryParameters,
        options: _checkOptions(method, options), cancelToken: cancelToken
    );

    // String fileEntityStr=url;
    // print("数据返回格式统  fileEntityStr-->$fileEntityStr");
    dynamic _code;
    dynamic _userTip;
    T? _data;
    // print("数据返回格式统  response-->$response");
    try {
      Map<String, dynamic> _map = json.decode(response?.data?.toString()??'');
      // Map<String, dynamic> _map = json.decode(fileEntityStr);
      print("数据返回格式统  request一-->$_map");
      _code = _map["code"];
      _userTip = _map["userTip"];
      if (_map.containsKey("data")){
        if(_map["data"] is String){
          _data=_map["data"];
        }else {
          _data = _map["data"]==null?null:generateOBJ!(_map["data"]);
        }
      }
    }catch(e){
      LogUtil.e(e);
      return BaseEntity(ExceptionHandle.parse_error, "数据解析错误", null);
    }
    return BaseEntity(
      _code, _userTip, _data,
    );
  }

  Future<BaseEntity<List<T>>> _requestList<T>(String method, String url, {
    dynamic data, Map<String, dynamic>? queryParameters,CancelToken? cancelToken, Options? options,Function? generateOBJ}) async {
    print("请求的参数 1-->method=${method},queryParameters=${queryParameters}");
    var response = await _dio?.request(url, data: data,queryParameters: queryParameters, options: _checkOptions(method, options), cancelToken: cancelToken);
    // print("返回的数据 -->data=${response.data}");
    dynamic _code;
    dynamic _userTip;
    List<T?>? _data = [];
    dynamic _totalElements=0;

//code: 1
// data: "Invalid token: 919547f6-3c35-4ed2-87d5-f3aaddb801ca"
// userTip: "用户凭证已过期"
// errorCode: "A0311"
// errorMessage: "token 过期"
// totalElements: 0
    try {
      Map<String, dynamic> _map = json.decode(response?.data?.toString()??'');
      // print("请求的接口 2-->code=${_map['code']},msg=${_map['msg']}");
      _code = _map["code"];
      _userTip = _map["userTip"];
      _totalElements = _map["totalElements"];
      if ((_map.containsKey("data"))&&(_map["data"] is List)){
        ///  List类型处理，暂不考虑Map
        (_map["data"] as List).forEach((item){
          _data?.add(generateOBJ!(item));
        });
        return BaseEntity(_code, _userTip, _data,totalElements: _totalElements);
      }else if((_map.containsKey("data"))&&((_map["data"] is String)||(_map["data"]==null) )){
        _data=[];
        return BaseEntity(_code, _userTip, _data,totalElements: _totalElements);
      }
    }catch(e){
      LogUtil.e(e);
      return BaseEntity(ExceptionHandle.parse_error, "数据解析错误", null);
    }
    return BaseEntity(_code, _userTip, _data,totalElements: _totalElements);
  }

  Future<BaseEntity<T>> request<T>(String method, String url, {
    bool isFormData:false,
    dynamic params,Map<String, dynamic>? queryParameters, CancelToken? cancelToken, Options? options,Function? generateOBJ,}) async {

    var response = await _request<T>(method, url,isFormData:isFormData,
        data: params,queryParameters: queryParameters, options: options, cancelToken: cancelToken,generateOBJ: generateOBJ);
    return response;
  }

  Future<BaseEntity<List<T>>> requestList<T>(String method, String url, {
    dynamic params,Map<String, dynamic>? queryParameters, CancelToken? cancelToken, Options? options,Function? generateOBJ}) async {
    var response = await _requestList<T>(method, url, data: params,queryParameters: queryParameters, options: options, cancelToken: cancelToken,generateOBJ: generateOBJ);
    return response;
  }

  /// 统一处理(onSuccess返回T对象，onSuccessList返回List<T>)
  Future<BaseEntity> requestNetwork<T>(String method, String url, {
    bool isList:false,
    bool isFormData:false,
    dynamic params,Map<String, dynamic>? queryParameters, CancelToken? cancelToken, Options? options,Function? generateOBJ})async{
    if(isList==null)isList=false;
    if(isFormData==null)isFormData=false;
    if(queryParameters==null)queryParameters={};
    LogUtil.e("listen： method=$method,url=$url,isList=$isList,isFormData=$isFormData,queryParameters=$queryParameters,options=$options");
    LogUtil.e("listen： params: ${params?.toString()}");
    try{
      var result= await ((!isList) ? request<T>(method, url,isFormData:isFormData,
          params: params,queryParameters: queryParameters, options: options, cancelToken: cancelToken,generateOBJ: generateOBJ) :
      requestList<T>(method, url, params: params, queryParameters:queryParameters,options: options, cancelToken: cancelToken,generateOBJ: generateOBJ));
      if((result.code??0)==401){
        //登录异常，直接退出登录
        // SpUtils.clear();
        // var instance = await JpushUtils.getInstance();
        // instance.stop();
        // NavigatorUtils.push(navigatorKey.currentContext, BaseRouter.loginPage,clearStack: true);
        return BaseEntity(
          result.code, result.userTip,result.data,totalElements: result.totalElements,
        );
      }else{
        print("请求的接口 0-->code=${result.code},userTip=${result.userTip}");
        return BaseEntity(
          result.code, result.userTip,result.data,totalElements: result.totalElements,
        );
      }
    }catch(e){
      // print("请求的接口 0-->e=${e.toString()}");
      Error error = ExceptionHandle.handleException(e);
      return BaseEntity(error.status, error.message,null);
    }
  }

  //
  // post<T>(String url, {bool isList:false,bool isFormData:false
  //   , dynamic params, CancelToken? cancelToken, Options? options,}){
  //
  //   return requestNetwork<T>("POST", url, isList: isList,
  //     isFormData: isFormData, params: params, queryParameters:{},options: options, cancelToken: cancelToken, );
  // }
  //
  // get<T>(String url, {bool isList:false, Map<String,dynamic>? params, Map<String, dynamic>? queryParameters,CancelToken? cancelToken, Options? options}){
  //   return requestNetwork<T>("GET", url, isList: isList, params: params,queryParameters: queryParameters, options: options, cancelToken: cancelToken);
  // }
  //
  // put<T>(String url, {bool isList:false,bool isFormData:false, Map<String,dynamic>? params, CancelToken? cancelToken, Options? options}){
  //   return requestNetwork<T>("PUT", url, isList: isList,isFormData: isFormData, params: params,queryParameters :{}, options: options, cancelToken: cancelToken);
  // }
  //
  // delete<T>(String url, {bool isList:false, Map<String,dynamic>? params, CancelToken? cancelToken, Options? options}){
  //   return requestNetwork<T>("DELETE", url, isList: isList, params: params,queryParameters :{}, options: options, cancelToken: cancelToken);
  // }


  /***********************************************/
  /*
   * 下载文件
   */
  downloadFile(urlPath, savePath,{Function(int count, int total)? onProgress,
    Function()? onSuccess,Function(Exception e)? onFail,Map<String, dynamic>? params,}) async {
    Response response;
    var options = BaseOptions(
      connectTimeout: 15000,
      receiveTimeout: 15000,
      responseType: ResponseType.plain,
      validateStatus: (status){
        // 不使用http状态码判断状态，使用AdapterInterceptor来处理（适用于标准REST风格）
        return true;
      },
//      baseUrl: Constant.BASE_URL,
//      contentType: ContentType('application', 'x-www-form-urlencoded', charset: 'utf-8'),
    );
    Dio _dio2 = Dio(options);
    /// 统一添加身份验证请求头
//    _dio2.interceptors.add(AuthInterceptor());
//    /// 刷新Token
//    _dio2.interceptors.add(TokenInterceptor());
//    /// 打印Log
//    _dio2.interceptors.add(LoggingInterceptor());
//    /// 适配数据
//    _dio2.interceptors.add(AdapterInterceptor());
    try {
      response = await _dio2.download(urlPath, savePath,data: params,onReceiveProgress: (int count, int total){
        //进度
        print("下载文件进度-->$count $total");
        if(onProgress!=null)onProgress(count,total);
      });
      if(onSuccess!=null)onSuccess();
      print('downloadFile success---------${response.data}');
    } on DioError catch (e) {
      print('downloadFile error---------$e');
//      formatError(e);
      if(onFail!=null)onFail(e);
    }
//    return response.data;
  }
  // 上传文件
  static Future<Response> uploadFile(String path ,{FormData? data}) async{
    var options = BaseOptions(
      connectTimeout: 15000,
      receiveTimeout: 15000,
      responseType: ResponseType.plain,
      validateStatus: (status){
        // 不使用http状态码判断状态，使用AdapterInterceptor来处理（适用于标准REST风格）
        return true;
      },
//      baseUrl: Constant.BASE_URL,
//      contentType: ContentType('application', 'x-www-form-urlencoded', charset: 'utf-8'),
    );
    Dio _dioUp = Dio(options);
    Response response = await _dioUp.post(path,data: data);
    print('uploadFile-->response=${response.toString()}');
    return response;
  }

}